package com.zhihesj.anan.utils;

import org.hyperic.sigar.*;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

@Configuration
public class SigarUtils {
    public static Sigar initSigar() {
        try {
            //此处只为得到依赖库文件的目录，可根据实际项目自定义
//            String file = Paths.get(PathKit.getWebRootPath(),  "files", "sigar",".sigar_shellrc").toString();
//            File classPath = new File(file).getParentFile();
//            String filePath = SigarUtils.class.getClassLoader().getResource("").toURI().getPath();
//            System.out.println(filePath);
            //这里我直接把文件路径写死了
            File classPath = new File("E:\\project\\java\\anan20200419\\src\\main\\dlls");

            String path = System.getProperty("java.library.path");
            String sigarLibPath = classPath.getCanonicalPath();
            //为防止java.library.path重复加，此处判断了一下
            if (!path.contains(sigarLibPath)) {
                if (isOSWin()) {
                    path += ";" + sigarLibPath;System.out.println(path);
                } else {
                    path += ":" + sigarLibPath;
                }
                System.setProperty("java.library.path", path);
            }
            return new Sigar();
        } catch (Exception e) {
            return null;
        }
    }

    public static boolean isOSWin(){//OS 版本判断
        String OS = System.getProperty("os.name").toLowerCase();
        if (OS.indexOf("win") >= 0) {
            return true;
        } else {
            return false;
        }
    }


    public static void sigarDemonstration(){
        try {
            SigarUtils s = new SigarUtils();
            s.initSigar();
            // System信息，从jvm获取
            property();
            System.out.println("----------------------------------");
            // cpu信息
            cpu();
            System.out.println("----------------------------------");
            // 内存信息
            memory();
            System.out.println("----------------------------------");
            // 操作系统信息
            os();
            System.out.println("----------------------------------");
            // 用户信息
            who();
            System.out.println("----------------------------------");
            // 文件系统信息
            file();
            System.out.println("----------------------------------");
            // 网络信息
            net();
            System.out.println("----------------------------------");
            // 以太网信息
            ethernet();
            System.out.println("----------------------------------");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    public static List<Map<String, Object>> property() throws UnknownHostException {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(16);
        Runtime r = Runtime.getRuntime();
        Properties props = System.getProperties();
        InetAddress addr = InetAddress.getLocalHost();
        String ip=addr.getHostAddress();


        map.put("serverName", System.getenv().get("COMPUTERNAME"));
        map.put("server", props.getProperty("os.name"));
        map.put("serverIp", ip);
        map.put("architecture", props.getProperty("os.arch"));

        map.put("javaName", props.getProperty("java.vm.name"));
        map.put("javaVersion", props.getProperty("java.version"));
        map.put("javaStartTime", props.getProperty("java.vm.specification.name"));
        map.put("javaRunTime", props.getProperty("java.vm.specification.name"));
        map.put("javaInstallPath", props.getProperty("java.home"));
        map.put("javaStartParm", props.getProperty("java.vm.specification.name"));

        list.add(map);
        return list;
    }

    public static List<Map<String, Object>> memory() throws SigarException {
        List<Map<String, Object>> list = new ArrayList<>();
        Sigar sigar = new Sigar();
        Mem mem = sigar.getMem();
        Swap swap = sigar.getSwap();

        Map<String, Object> map = new HashMap<>();
        map.put("info", "总内存");
        map.put("memory", mem.getTotal() / 1024L);
        map.put("jvm", swap.getTotal() / 1024L);
        list.add(map);

        Map<String, Object> map1 = new HashMap<>();
        map1.put("info", "剩余内存");
        map1.put("memory", mem.getFree() / 1024L);
        map1.put("jvm", swap.getUsed() / 1024L);
        list.add(map1);

        Map<String, Object> map2 = new HashMap<>();
        map2.put("info", "已用内存");
        map2.put("memory", mem.getUsed() / 1024L);
        map2.put("jvm", swap.getFree() / 1024L);
        list.add(map2);

        Map<String, Object> map3 = new HashMap<>();
        map3.put("info", "使用率");
        map3.put("memory", mem.getUsed() / mem.getTotal());
        map3.put("jvm", swap.getTotal() / swap.getFree());
        list.add(map3);
        return list;
    }


    public static List<Map<String, Object>> cpu() throws SigarException {
        List<Map<String, Object>> list = new ArrayList<>();
        Sigar sigar = new Sigar();
        CpuInfo[] infos = sigar.getCpuInfoList();
        CpuPerc[] cpuList = null;
        cpuList = sigar.getCpuPercList();
        Integer integer=0;
        Double db=0D;

        // 不管是单块CPU还是多CPU都适用
        for (int i = 0; i < infos.length; i++) {
            CpuInfo info = infos[i];
            // CPU的总量MHz
            integer+=info.getMhz();
            db+=cpuList[i].getUser();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("info", "cpu核心数");
        map.put("value",infos.length);
        list.add(map);

        Map<String, Object> map1 = new HashMap<>();
        map1.put("info", "cpu最大功率");
        map1.put("value",integer);
        list.add(map1);

        Map<String, Object> map2= new HashMap<>();
        map2.put("info", "cpu用户使用率");
        map2.put("value", CpuPerc.format(db / infos.length ));
        list.add(map2);

        return list;
    }

    public static void printCpuPerc(CpuPerc cpu) {
        // 用户使用率
        System.out.println("CPU用户使用率:    " + CpuPerc.format(cpu.getUser()));
        // 系统使用率
        System.out.println("CPU系统使用率:    " + CpuPerc.format(cpu.getSys()));
        // 当前等待率
        System.out.println("CPU当前等待率:    " + CpuPerc.format(cpu.getWait()));
        //
        System.out.println("CPU当前错误率:    " + CpuPerc.format(cpu.getNice()));
        // 当前空闲率
        System.out.println("CPU当前空闲率:    " + CpuPerc.format(cpu.getIdle()));
        // 总的使用率
        System.out.println("CPU总的使用率:    " + CpuPerc.format(cpu.getCombined()));
    }

    public static void os() {
        OperatingSystem OS = OperatingSystem.getInstance();
        // 操作系统内核类型如： 386、486、586等x86
        System.out.println("操作系统:    " + OS.getArch());
        System.out.println("操作系统CpuEndian():    " + OS.getCpuEndian());
        System.out.println("操作系统DataModel():    " + OS.getDataModel());
        // 系统描述
        System.out.println("操作系统的描述:    " + OS.getDescription());
        // 操作系统类型
        // System.out.println("OS.getName():    " + OS.getName());
        // System.out.println("OS.getPatchLevel():    " + OS.getPatchLevel());
        // 操作系统的卖主
        System.out.println("操作系统的卖主:    " + OS.getVendor());
        // 卖主名称
        System.out.println("操作系统的卖主名:    " + OS.getVendorCodeName());
        // 操作系统名称
        System.out.println("操作系统名称:    " + OS.getVendorName());
        // 操作系统卖主类型
        System.out.println("操作系统卖主类型:    " + OS.getVendorVersion());
        // 操作系统的版本号
        System.out.println("操作系统的版本号:    " + OS.getVersion());
    }

    public static void who() throws SigarException {
        Sigar sigar = new Sigar();
        Who who[] = sigar.getWhoList();
        if (who != null && who.length > 0) {
            for (int i = 0; i < who.length; i++) {
                // System.out.println("当前系统进程表中的用户名" + String.valueOf(i));
                Who _who = who[i];
                System.out.println("用户控制台:    " + _who.getDevice());
                System.out.println("用户host:    " + _who.getHost());
                // System.out.println("getTime():    " + _who.getTime());
                // 当前系统进程表中的用户名
                System.out.println("当前系统进程表中的用户名:    " + _who.getUser());
            }
        }
    }

    public static List<Map<String,Object>> file() throws Exception {
        List<Map<String, Object>> list = new ArrayList<>();

        Sigar sigar = new Sigar();
        FileSystem fslist[] = sigar.getFileSystemList();
        Map<String,Object> map=null;

        for (int i = 0; i < fslist.length; i++) {
            map = new HashMap<>();
            FileSystem fs = fslist[i];
//            // 分区的盘符名称
            map.put("diskName", fs.getDevName());
//            // 文件系统类型
            map.put("fineSys", fs.getSysTypeName());
//            // 文件系统类型，比如 FAT32、NTFS
            map.put("diskType", fs.getType());
            map.put("diskTypeName", fs.getTypeName());
            // 盘符路径
            map.put("diskHost", fs.getDirName());

//            System.out.println("盘符路径:    " + fs.getDirName());
//            System.out.println("盘符标志:    " + fs.getFlags());//
//            // 文件系统类型名，比如本地硬盘、光驱、网络文件系统等
//            System.out.println("盘符类型名:    " + fs.getTypeName());

            FileSystemUsage usage = sigar.getFileSystemUsage(fs.getDirName());
            switch (fs.getType()) {
                // TYPE_UNKNOWN ：未知
                case 0:
                    break;
                // TYPE_NONE
                case 1:
                    break;
                // TYPE_LOCAL_DISK : 本地硬盘
                case 2:
                    // 文件系统总大小
                    map.put("totalSize", usage.getTotal()/1024/1024 + "GB");
                    // 文件系统可用大小
                    map.put("svailableSize", usage.getAvail()/1024/1024 + "GB");
                    // 文件系统已经使用量
                    map.put("usedSize", usage.getUsed()/1024/1024 + "GB");
                    // 文件系统资源的利用率
                    double usePercent = usage.getUsePercent() * 100D;
                    map.put("percentageUsed",  usePercent + "%");
                    // 文件系统剩余大小 System.out.println(fs.getDevName() + "剩余大小:    " + usage.getFree() + "KB");
                    break;
                // TYPE_NETWORK ：网络
                case 3:
                    break;
                // TYPE_RAM_DISK ：闪存
                case 4:
                    break;
                // TYPE_CDROM ：光驱
                case 5:
                    break;
                // TYPE_SWAP ：页面交换
                case 6:
                    break;
            }
//            System.out.println(fs.getDevName() + "读出：    " + usage.getDiskReads());
//            System.out.println(fs.getDevName() + "写入：    " + usage.getDiskWrites());
            list.add(map);
        }
        return list;
    }

    public static void net() throws Exception {
        Sigar sigar = new Sigar();
        String ifNames[] = sigar.getNetInterfaceList();
        for (int i = 0; i < ifNames.length; i++) {
            String name = ifNames[i];
            NetInterfaceConfig ifconfig = sigar.getNetInterfaceConfig(name);
            // 网络设备名
            System.out.println("网络设备名:    " + name);
            // IP地址
            System.out.println("IP地址:    " + ifconfig.getAddress());
            // 子网掩码
            System.out.println("子网掩码:    " + ifconfig.getNetmask());
            if ((ifconfig.getFlags() & 1L) <= 0L) {
                System.out.println("!IFF_UP...skipping getNetInterfaceStat");
                continue;
            }
            NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name);
            // 接收的总包裹数
            System.out.println(name + "接收的总包裹数:" + ifstat.getRxPackets());
            // 发送的总包裹数
            System.out.println(name + "发送的总包裹数:" + ifstat.getTxPackets());
            // 接收到的总字节数
            System.out.println(name + "接收到的总字节数:" + ifstat.getRxBytes());
            // 发送的总字节数
            System.out.println(name + "发送的总字节数:" + ifstat.getTxBytes());
            // 接收到的错误包数
            System.out.println(name + "接收到的错误包数:" + ifstat.getRxErrors());
            // 发送数据包时的错误数
            System.out.println(name + "发送数据包时的错误数:" + ifstat.getTxErrors());
            // 接收时丢弃的包数
            System.out.println(name + "接收时丢弃的包数:" + ifstat.getRxDropped());
            // 发送时丢弃的包数
            System.out.println(name + "发送时丢弃的包数:" + ifstat.getTxDropped());
        }
    }

    public static void ethernet() throws SigarException {
        Sigar sigar = null;
        sigar = new Sigar();
        String[] ifaces = sigar.getNetInterfaceList();
        for (int i = 0; i < ifaces.length; i++) {
            NetInterfaceConfig cfg = sigar.getNetInterfaceConfig(ifaces[i]);
            if (NetFlags.LOOPBACK_ADDRESS.equals(cfg.getAddress()) || (cfg.getFlags() & NetFlags.IFF_LOOPBACK) != 0
                    || NetFlags.NULL_HWADDR.equals(cfg.getHwaddr())) {
                continue;
            }
            // IP地址
            System.out.println(cfg.getName() + "IP地址:" + cfg.getAddress());
            // 网关广播地址
            System.out.println(cfg.getName() + "网关广播地址:" + cfg.getBroadcast());
            // 网卡MAC地址
            System.out.println(cfg.getName() + "网卡MAC地址:" + cfg.getHwaddr());
            // 子网掩码
            System.out.println(cfg.getName() + "子网掩码:" + cfg.getNetmask());
            // 网卡描述信息
            System.out.println(cfg.getName() + "网卡描述信息:" + cfg.getDescription());
            System.out.println(cfg.getName() + "网卡类型" + cfg.getType());
        }
    }

}